<?php


namespace App\Order\Service\Order;

use App\Order\Model\OrderModel;

use Hyperf\Contract\LengthAwarePaginatorInterface;
use Hyperf\Database\Model\Builder;
use Hyperf\Database\Model\Model;
use Hyperf\Di\Annotation\Inject;
use App\Common\Constants\Stakeholder;

class OrderAdminService extends OrderBaseService implements OrderServiceInterface
{

    /**
     * @Inject()
     * @var OrderRefundService
     */
    protected $orderRefundService;

    /**
     * 后台订单列表
     * @param array $where
     * @param array $field
     * @return mixed
     */
    public function getList(array $where = [], array $field = ['*'])
    {
        $order = $this->getListResult($where, $field);
        if (isset($where['perpage']) && !empty($where['perpage'])) {
            $items = $order->items();
        } else {
            $items = $order->toArray();
        }
        $orderNoArr = array_unique(array_column($items, 'order_no'));
        $refundInfo = $this->orderRefundService->refundInfo($orderNoArr);
        $refund = [];
        foreach ($order as $k => $v) {
            $order[$k]['phone'] = $v['order_phone'];
            $order[$k]['refund_type'] = is_null($v['refund_at']) ? '':'部分退';
            $order[$k]['refund_at'] = $v['refund_at'] ?? '--';
            if ($v['address_id'] == 0) {
                // 自提单
                $order[$k]['receive_username'] = $v['nickname']; //收货人姓名
                $order[$k]['receive_phone'] = $v['mem_phone']; //收货人手机号码
            } else {
                // 配送单
                $order[$k]['receive_username'] = $v['addr_username'];
                $order[$k]['receive_phone'] = $v['addr_phone'];
            }
            // 退款信息
            if (($v['is_pay'] == Stakeholder::ORDER_PAID)) {
                if (isset($refundInfo['wxRefund'][$v['order_no']]) || isset($refundInfo['kzRefund'][$v['order_no']])) {
                    $refund['refund_freight'] = '0.00';// 退款运费
                    if ($v['pay_type'] == Stakeholder::PAYMENT_METHOD_WECHAT) {
                        // 微信支付
                        $refund['refund_wx_money'] = $refundInfo['wxRefund'][$v['order_no']] ?? '0.00';
                        $refund['refund_total'] = $refund['refund_wx_money']; // 退款总金额
                    }
                    if ($v['pay_type'] == Stakeholder::PAYMENT_METHOD_BALANCE) {
                        // 余额支付
                        $refund['refund_balance_money'] = $refundInfo['kzRefund'][$v['order_no']] ?? '0.00';
                        $refund['refund_total'] = $refund['refund_balance_money']; // 退款总金额
                    }
                    if ($v['status'] == Stakeholder::ORDER_REFUNDED) {
                        if ($v['is_whole'] == Stakeholder::WHOLE_REFUND) {
                            $refund['refund_freight'] = bcsub((string)$v['freight_price'], (string)$v['coupon_freight_cut'], 2);// 退款运费
                            $refund['refund_total'] = $v['total_price']; // 退款总金额
                            $order[$k]['refund_type'] = '全部退';
                        }
                    }
                }
            }
            $order[$k]['refund'] = $refund ?? [];
            unset($refund);
        }
        return $order;
    }

    public function update()
    {
        // TODO: Implement update() method.
    }

    public function delete()
    {
        // TODO: Implement delete() method.
    }

    /**
     * 后台订单详情
     */
    public function info(array $where = [], array $field = ['*'], string $refund_no = null){
        $orderInfo = $this->findFirst($where, $field);
        $order = [
            'order_no' => $orderInfo->order_no, //订单编号
            'refund_no' => $refund_no, //退款单号
            'nickname' => $orderInfo->member->nickname, //用户昵称
            'order_phone' => $orderInfo->member->phone, //手机号码
            'kz_cus_code' => $orderInfo->member->kz_cus_code, //客至编号
            'deal_type' => $orderInfo->deal_type, //配送方式 1配送订单,2为自提订单
            'status' => $orderInfo->status, //订单状态
            'order_type' => $orderInfo->order_type, //订单类型
            'shop_name' => $orderInfo->shop->shop_name, //下单店铺
            'shop_phone' => $orderInfo->shop->shop_tel, //店铺电话
            'shop_time' => $orderInfo->shop->shop_desc, //营业时间
            'shop_address' => $orderInfo->shop->address, //营业时间
            'create_at' => $orderInfo->create_at, //下单时间
            'pay_at' => $orderInfo->pay_at, //支付时间
            'is_whole' => $orderInfo->is_whole, //0：整单  1：部分
            'appointment_time' => $orderInfo->appointment_time, //配送时间(自提时间)
            'apply_refund_at' => $orderInfo->refund->create_at ?? '', //申请退款时间
            'complete_date' => $orderInfo->complete_date, //订单完成时间
            'refund_at' => $orderInfo->refund_at ?? '', //退款完成时间
            'order_source' => $orderInfo->order_source ?? 0, //0、及时达 1 次日达
            'order_commission' => $orderInfo->order_commission ?? '0.00' //退款完成时间
        ];
        if ($orderInfo->deal_type == Stakeholder::ORDER_SELF_PICK) {
            // 自提订单
            $order['receive_name'] = $orderInfo->member->nickname;
            $order['receive_phone'] = $orderInfo->member->phone;
            $order['receive_address'] = $orderInfo->shop->address;
        } else {
            $order['receive_name'] = $orderInfo->address->username;
            $order['receive_phone'] = $orderInfo->address->phone;
            $order['receive_address'] = $orderInfo->address->address;
        }
        return $order;
    }

    /** 后台订单详情-商品信息 */
    public function infoGoods(array $where = [], array $field = ['*']){
        $list = $this->goodsResult($where, $field);
        $order_source = $this->findFirst($where, ['order_source'])['order_source'];
        foreach ($list as $k => $v) {
            $list[$k]['subtotal'] = $v['dis_price']; // 小计
            $list[$k]['refund_subtotal'] = $v['refund_price']; // 退款小计
            $list[$k]['refund_num'] = $v['number'] - $v['refund_number'] - $v['shop_refund_number']; // 退款数量
            $list[$k]['order_source'] = $order_source;
        }
        return $list;
    }

    /**
     * 后台订单详情-费用信息
     * @param array $where
     * @param array|string[] $field
     * @return Builder|Model|object|null
     */
    public function infoCost(array $where = [], array $field = ['*'])
    {
        $cost = $this->findFirst($where, $field);
        $cost->sum_amount = $cost->total_price; // 应付款金额
        $cost->activity = 0; // 优惠活动
        $cost->discount = 0; // 折扣金额
        return $cost;
    }
    /**
     * 后台财务订单导出
     * @param array $where
     * @param array|string[] $field
     * @param int $flag
     * @return LengthAwarePaginatorInterface
     */
    public function export(array $where = [], array $field = ['*'], int $flag)
    {

        switch ($flag) {
            case 1:
                // 财务订单导出
                $order = $this->getListResult($where, $field);

                if (isset($where['perpage']) && !empty($where['perpage'])) {
                    $items = $order->items();
                } else {
                    $items = $order->toArray();
                }

                $orderNoArr = array_unique(array_column($items, 'order_no'));
                $refund = $this->orderRefundService->refundInfo($orderNoArr);

                foreach ($order as $k => $v) {
                    // 商品原金额
                    $order[$k]['original_amt'] = bcadd((string)$v['goods_price'], bcsub((string)$v['coupon_cut'], (string)$v['coupon_freight_cut'], 2), 2);
                    // 应收金额
                    $order[$k]['receivable_amt'] = bcadd($order[$k]['original_amt'], (string)$v['freight_price'], 2);
                    $order[$k]['refund_at'] = $v['refund_at'] ?? '';
                    // 微信退款金额
                    $order[$k]['refundWxMoney'] = $refund['wxRefund'][$v['order_no']] ?? '0.00';
                    // 余额退款金额
                    $order[$k]['refundKzMoney'] = $refund['kzRefund'][$v['order_no']] ?? '0.00';
                    // 实际实收金额
                    $order[$k]['true_receivable_amt'] = bcsub((string)$v['total_price'],bcadd((string)$order[$k]['refundWxMoney'], (string)$order[$k]['refundKzMoney'], 2),2);
                }
                break;
            case 2:
                // 拼团配货单
                $order = $this->distribution($where, $field, $flag);
                break;
            case 3:
                // 疏东坡模板导出
                $res = $this->shuDongPoTemp($where, $field);
                $order = [];
                foreach ($res->toArray() as $k => $v){
                    $key = $v['shop_id'] . $v['goods_title'];
                    if(!isset($order[$key])){
                        $order[$key] = $v;
                    }else{
                        $order[$key]['num'] = bcadd((string)$order[$key]['num'], (string)$v['num'], 4);
                    }
                }
                $order = array_values($order);
                break;
            default:
        }
        return $order;
    }

    /**
     * 导出拼团配货单
     * @param array $where
     * @param array $field
     * @param int $flag
     * @return array
     */
    public function distribution(array $where, array $field, int $flag)
    {
        $where = $this->conditionWhere($where);
        $shopNameArr = $this->container->get(ShopService::class)->getShopNameData();
        $order = OrderModel::query()
            ->from('store_order as order')
            ->leftJoin('store_order_goods as og', 'order.order_no', '=', 'og.order_no')
            ->selectRaw(implode(',', $field))
            ->when($where['create_at'] ?? 0, function ($query, $create_at) {
                return $query->whereBetween('order.create_at', $create_at);
            })
            ->when($where['pay_at'] ?? 0, function ($query, $pay_at) {
                return $query->whereBetween('order.pay_at', $pay_at);
            })
            ->when($where['complete_date'] ?? 0, function ($query, $complete_date) {
                return $query->whereBetween('order.complete_date', $complete_date);
            })
            ->when($where['pay_type'] ?? 0, function ($query, $pay_type) {
                return $query->where('order.pay_type', $pay_type);
            })
            ->when(is_numeric($where['order_type']), function ($query) use ($where) {
                return $query->where('order.order_type', $where['order_type']);
            })
            ->when(is_numeric($where['order_source']), function ($query) use ($where) {
                return $query->where('order.order_source', $where['order_source']);
            })
            ->whereNotIn('order.status', [Stakeholder::ORDER_CANCEL, Stakeholder::ORDER_REFUNDED])
            ->groupBy(['shop_id', 'goods_id'])
            ->when($param['perpage'] ?? 0, function ($query, $perPage) {
                return $query->paginate((int)$perPage);
            }, function ($query) {
                return $query->get();
            });
        if (isset($where['perpage']) && !empty($where['perpage'])) {
            $items = $order->items();
        } else {
            $items = $order->toArray();
        }
        if (!empty($items)) {
            $list = [];
            $goodsInfo = array_unique(array_column($items, 'goods_title', 'goods_id'));
            $diff = array_fill_keys(array_keys($goodsInfo), 0);
            ksort($goodsInfo);
            $goodsInfo = ['header' => '门店'] + $goodsInfo;
            foreach ($order as $k => $v) {
                foreach ($shopNameArr as $kk => $vv) {
                    $list[$kk]['shop_name'] = $vv;
                    if ($v['shop_id'] == $kk) {
                        $list[$v['shop_id']][$v['goods_id']] = (int)$v['num'];
                    }
                }
            }
            foreach ($list as $k => $v) {
                $map = $v + $diff;
                ksort($map);
                $list[$k] = $map;
            }
            // 合计
            foreach ($items as $k => $v) {
                $diff[$v['goods_id']] += $v['num'];
            }
            array_unshift($list, $goodsInfo);
            $endMap = ['shop_name' => '合计'] + $diff;
            ksort($endMap);
            array_push($list, $endMap);
            return $list;
        }
        return $order;
    }

    /**
     * 导出疏东坡报货模板
     * @param array $where
     * @param array $field
     * @return \Hyperf\Database\Concerns\BuildsQueries|Builder|\Hyperf\Database\Query\Builder|mixed
     */
    public function shuDongPoTemp(array $where, array $field)
    {
        $where = $this->conditionWhere($where);
        $order = OrderModel::query()
            ->from('store_order as order')
            ->leftJoin('store_shop as shop', 'order.shop_id', '=', 'shop.shop_id')
            ->leftJoin('store_order_goods as og', 'order.order_no', '=', 'og.order_no')
            ->leftJoin('store_goods as g', 'og.goods_id', '=', 'g.id')
            ->selectRaw(implode(',', $field))
            ->when($where['create_at'] ?? 0, function ($query, $create_at) {
                return $query->whereBetween('order.create_at', $create_at);
            })
            ->when($where['pay_at'] ?? 0, function ($query, $pay_at) {
                return $query->whereBetween('order.pay_at', $pay_at);
            })
            ->when($where['complete_date'] ?? 0, function ($query, $complete_date) {
                return $query->whereBetween('order.complete_date', $complete_date);
            })
            ->when($where['pay_type'] ?? 0, function ($query, $pay_type) {
                return $query->where('order.pay_type', $pay_type);
            })
            ->when(is_numeric($where['order_type']), function ($query) use ($where) {
                return $query->where('order.order_type', $where['order_type']);
            })
            ->when(is_numeric($where['order_source']), function ($query) use ($where) {
                return $query->where('order.order_source', $where['order_source']);
            })
            ->when($where['shop_id'] ?? 0, function ($query, $shop_id) {
                return $query->where('order.shop_id', $shop_id);
            })
            ->when($where['goods_name'] ?? 0, function ($query, $goods_name) {
                return $query->whereRaw('INSTR(og.goods_title, ?) > 0', [$goods_name]);
            })
            ->whereNotIn('order.status', [Stakeholder::ORDER_CANCEL,Stakeholder::ORDER_RECEIVED, Stakeholder::ORDER_REFUNDED])
            ->groupBy(['shop_id', 'goods_id'])
            ->when($param['perpage'] ?? 0, function ($query, $perPage) {
                return $query->paginate((int)$perPage);
            }, function ($query) {
                return $query->get();
            });
        return $order;
    }



}